/**
 * $Id: Actions.js,v 1.9 2013/04/10 11:26:47 gaudenz Exp $
 * Copyright (c) 2006-2012, JGraph Ltd
 */
/**
 * Constructs the actions object for the given UI.
 */


function Actions(editorUi)
{
    this.editorUi = editorUi;
    this.actions = new Object();
    this.init();
}
;

/**
 * Adds the default actions.
 */
Actions.prototype.init = function()
{
    var ui = this.editorUi;
    var editor = ui.editor;
    var graph = editor.graph;



    $(function() {
        $.ajax({
            url: "ajax/getProjects.jsp",
            type: "POST",
            data: {id: "-1"},
            dataType: "html"
        }).done(function(data) {
            ui.showDialog(new openDataDialog(ui, "<div class='projectsTabel'><table>" + data + "</table></div>").container, 320, 280, true, true);





            $("table").on("click", ".delbt", function(event) {


                var C = confirm("Are you sure you want to delete Project? ");

                if (C) {

                    var ob = $(this);

                    $.ajax({
                        url: "ajax/delete.jsp",
                        type: "POST",
                        data: {id: ob.attr("id")},
                        dataType: "html"
                    }).done(function(data) {


                        ob.parent("td").parent("tr").remove()
                        alert("Project Deleted.");
                    })
                } else {



                }

            });



            $("table").on("dblclick", ".myprorow", function(event) {


                var xmlData = $(this).children(".opxml").val();

                var r = $(this);



                $.ajax({
                    url: "ajax/updateXml.jsp",
                    type: "POST",
                    data: {
                        xml: xmlData
                    },
                    dataType: "html"
                }).done(function(data) {

                    editor.addFromStatus = 1;
                    var doc = mxUtils.parseXml(data);


                    ui.editor.setGraphXml(doc.documentElement);
                    ui.hideDialog();

                    editor.updateDataArray(ui.editor.graph.getModel().getParent());

                    if (r.attr("id") != null) {
                        var a = r.attr("id").replace("row_", "");

                        $.ajax({
                            url: "ajax/session.jsp",
                            type: "POST",
                            data: {
                                value: a,
                                variable: "proid",
                                status: "create"
                            },
                            dataType: "html"
                        }).done(function(data2) {
                        })


                    }
                    editor.addFromStatus = "0";

                });





            });



        });

    })



    this.addAction('save', function() {


        $.ajax({
            url: "ajax/update.jsp",
            type: "POST",
            data: {
                // data: mxUtils.getPrettyXml(ui.editor.getGraphXml())
                data: editor.saveXml()


            },
            dataType: "html"
        }).done(function(data) {
            //   ui.hideDialog();
            alert(data);

        });




    }, null, null, 'Ctrl+S');


    this.addAction('saveAs', function() {
        ui.showDialog(new SaveDataDialog(ui, editor).container, 320, 280, true, true);





    }, null, null, 'Ctrl+Shift-S');

    this.put('editFile', new Action("View XML", mxUtils.bind(this, function()
    {


        /*var vxml = editor.saveXml() + mxUtils.getPrettyXml(ui.editor.getGraphXml()) + */

        //editor.readXML(editor.saveXml());
        //  alert(editor.saveXml());
        // var vxml = mxUtils.getPrettyXml(ui.editor.getGraphXml())

        var vxml = editor.saveXml();



        this.editorUi.showDialog(new EditFileDialog(ui, formatXml(vxml)).container, 600, 480, true, true);

    })));



    function formatXml(xml) {
        var formatted = '';
        var reg = /(>)(<)(\/*)/g;
        xml = xml.replace(reg, '$1\r\n$2$3');
        var pad = 0;
        jQuery.each(xml.split('\r\n'), function(index, node) {
            var indent = 0;
            if (node.match(/.+<\/\w[^>]*>$/)) {
                indent = 0;
            } else if (node.match(/^<\/\w/)) {
                if (pad != 0) {
                    pad -= 1;
                }
            } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) {
                indent = 1;
            } else {
                indent = 0;
            }

            var padding = '';
            for (var i = 0; i < pad; i++) {
                padding += '  ';
            }

            formatted += padding + node + '\r\n';
            pad += indent;
        });

        return formatted;
    }




// File actions
    this.addAction('addtoLast', function() {
        editor.addtoLast("");
    });



// File actions
    this.addAction('addtoFirst', function() {
        editor.addtoFirst("");
    });





// File actions
    this.addAction('toLast', function() {
        editor.swimtoLast("");
    });



    // File actions
    this.addAction('toFirst', function() {
        editor.swimtoFirst();

    });





// File actions
    this.addAction('toRight', function() {
        editor.swimToRight("");
    });



    // File actions
    this.addAction('toLeft', function() {
        editor.swimToLeft();

    });
    // File actions
    this.addAction('addChild', function() {
        editor.addChild();

    }, null, 'all-print', 'Ctrl+M');





//


// File actions
    this.addAction('addbelow', function() {
        editor.addswimToRight("");
    });



    // File actions
    this.addAction('addtop', function() {
        editor.addswimToLeft();

    });





// File actions
    this.addAction('addtoRight', function() {
        editor.addswimToRight("");
    });



    // File actions
    this.addAction('addtoLeft', function() {
        editor.addswimToLeft();

    });


    // File actions
    this.addAction('new', function() {
        window.open(ui.getUrl());
    });
    this.addAction('open', function()
    {
        window.openNew = true;
        window.openKey = 'open';

        ui.openFile();
    });
    this.addAction('import', function()
    {
        window.openNew = false;
        window.openKey = 'import';

        // Closes dialog after open
        window.openFile = new OpenFile(mxUtils.bind(this, function()
        {
            ui.hideDialog();
        }));

        window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
        {
            try
            {
                var doc = mxUtils.parseXml(xml);
                var model = new mxGraphModel();
                var codec = new mxCodec(doc);
                codec.decode(doc.documentElement, model);

                var children = model.getChildren(model.getChildAt(model.getRoot(), 0));
                editor.graph.setSelectionCells(editor.graph.importCells(children));
            }
            catch (e)
            {
                mxUtils.alert(mxResources.get('invalidOrMissingFile') + ': ' + e.message);
            }
        }));

        // Removes openFile if dialog is closed
        ui.showDialog(new OpenDialog(this).container, 300, 180, true, true, function()
        {
            window.openFile = null;
        });
    });






    this.addAction('export', function() {
        ui.showDialog(new ExportDialog(ui).container, 300, 200, true, true);
    }, null, null, 'Ctrl+E');

    this.addAction('pageSetup', function() {
        ui.showDialog(new PageSetupDialog(ui).container, 300, 200, true, true);
    });
    this.addAction('print', function() {
        ui.showDialog(new PrintDialog(ui).container, 300, 200, true, true);
    }, null, 'sprite-print', 'Ctrl+P');
    this.addAction('preview', function() {
        mxUtils.show(graph, null, 10, 10);
    });

    // Edit actions
    this.addAction('undo', function() {
        editor.undoManager.undo();



        editor.disableUndo = 1;

        setTimeout(doSomething, 200);

        function doSomething() {
            editor.reupdateDataArray();
            editor.disableUndo = 0;
        }


    }, null, 'sprite-undo', 'Ctrl+Z');
    this.addAction('redo', function() {
        editor.undoManager.redo();
        editor.disableUndo = 1;
        setTimeout(doSomething, 200);

        function doSomething() {
            editor.reupdateDataArray();
        }
        editor.disableUndo = 0;

    }, null, 'sprite-redo', 'Ctrl+Y');
    this.addAction('cut', function() {
        mxClipboard.cut(graph);

        editor.reupdateDataArray();



    }, null, 'sprite-cut', 'Ctrl+X');


    this.addAction('copy', function() {
        mxClipboard.copy(graph);

    }, null, 'sprite-copy', 'Ctrl+C');


    this.addAction('copynewid', function() {
        mxClipboard.copy(graph);


        var cell = graph.getSelectionCells()[0];





    }, null, 'sprite-copy', 'Ctrl+C');



    this.addAction('opaste', function() {
        mxClipboard.paste(graph);

        var cell = graph.getSelectionCells()[0];

        if (editor.isSwimLane(cell)) {

            cell.value.setAttribute('itemid', "");

        } else {
            if (cell.getAttribute('itemid', '-1') == '-1') {
                alert("cell havent itemid");
                graph.removeCells([cell]);


            }
            editor.reupdateDataArray();
        }



    }, false, 'sprite-paste', 'Ctrl+V');


    //

    this.addAction('paste', function() {
        mxClipboard.paste(graph);
        editor.reupdateDataArray();

        var cell = graph.getSelectionCells()[0];

        cell.value.setAttribute('itemid', "");

    }, false, 'sprite-paste', 'Ctrl+V');


    this.addAction('delete', function()
    {
        // Handles special case where delete is pressed while connecting
        if (graph.connectionHandler.isConnecting())
        {
            graph.connectionHandler.reset();
        }
        else
        {
            graph.removeCells();
        }
    }, null, null, 'Delete');
    this.addAction('duplicate', function()
    {
        var s = graph.gridSize;
        graph.setSelectionCells(graph.moveCells(graph.getSelectionCells(), s, s, true));
    }, null, null, 'Ctrl+D');
    this.addAction('selectVertices', function() {
        graph.selectVertices();
    }, null, null, 'Ctrl+Shift+V');
    this.addAction('selectEdges', function() {
        graph.selectEdges();
    }, null, null, 'Ctrl+Shift+E');
    this.addAction('selectAll', function() {
        graph.selectAll();
    }, null, null, 'Ctrl+A');
    this.addAction('lockUnlock', function()
    {
        graph.getModel().beginUpdate();
        try
        {
            graph.toggleCellStyles(mxConstants.STYLE_RESIZABLE, 1);
            graph.toggleCellStyles(mxConstants.STYLE_MOVABLE, 1);
            graph.toggleCellStyles(mxConstants.STYLE_ROTATABLE, 1);
        }
        finally
        {
            graph.getModel().endUpdate();
        }
    }, null, null, 'Ctrl+L');

    // Navigation actions
    this.addAction('home', function() {
        graph.home();
    }, null, null, 'Home');
    this.addAction('exitGroup', function() {
        graph.exitGroup();
    }, null, null, 'Page Up');
    this.addAction('enterGroup', function() {
        graph.enterGroup();
    }, null, null, 'Page Down');
    this.addAction('expand', function() {
        graph.foldCells(false);
    }, null, null, 'Enter');
    this.addAction('collapse', function() {
        graph.foldCells(true);
    }, null, null, 'Backspace');

    // Arrange actions
    this.addAction('toFront', function() {
        graph.orderCells(false);
    }, null, null, 'Ctrl+F');
    this.addAction('toBack', function() {
        graph.orderCells(true);
    }, null, null, 'Ctrl+B');
    this.addAction('group', function() {
        graph.setSelectionCell(graph.groupCells(null, 0));
    }, null, null, 'Ctrl+G');
    this.addAction('ungroup', function() {
        graph.setSelectionCells(graph.ungroupCells());
    }, null, null, 'Ctrl+U');
    this.addAction('removeFromGroup', function() {
        graph.removeCellsFromParent();
    });
    this.addAction('editLink', function()
    {
        var cell = graph.getSelectionCell();
        var link = graph.getLinkForCell(cell);

        if (link == null)
        {
            link = '';
        }

        link = mxUtils.prompt(mxResources.get('enterValue'), link);

        if (link != null)
        {
            graph.setLinkForCell(cell, link);
        }
    });
    this.addAction('openLink', function()
    {
        var cell = graph.getSelectionCell();
        var link = graph.getLinkForCell(cell);

        if (link != null)
        {
            window.open(link);
        }
    });
    this.addAction('autosize', function()
    {
        var cells = graph.getSelectionCells();

        if (cells != null)
        {
            graph.getModel().beginUpdate();
            try
            {
                for (var i = 0; i < cells.length; i++)
                {
                    var cell = cells[i];

                    if (graph.getModel().getChildCount(cell))
                    {
                        graph.updateGroupBounds([cell], 20);
                    }
                    else
                    {
                        graph.updateCellSize(cell);
                    }
                }
            }
            finally
            {
                graph.getModel().endUpdate();
            }
        }
    });
    this.addAction('wordWrap', function()
    {
        var state = graph.getView().getState(graph.getSelectionCell());
        var value = 'wrap';

        if (state != null && state.style[mxConstants.STYLE_WHITE_SPACE] == 'wrap')
        {
            value = null;
        }

        graph.setCellStyles(mxConstants.STYLE_WHITE_SPACE, value);
    });
    this.addAction('rotation', function()
    {
        var value = '0';
        var state = graph.getView().getState(graph.getSelectionCell());

        if (state != null)
        {
            value = state.style[mxConstants.STYLE_ROTATION] || value;
        }

        value = mxUtils.prompt(mxResources.get('enterValue') + ' (' +
                mxResources.get('rotation') + ' 0-360)', value);

        if (value != null)
        {
            graph.setCellStyles(mxConstants.STYLE_ROTATION, value);
        }
    });
    this.addAction('tilt', function()
    {
        var cells = graph.getSelectionCells();

        if (cells != null)
        {
            graph.getModel().beginUpdate();
            try
            {
                for (var i = 0; i < cells.length; i++)
                {
                    var cell = cells[i];

                    if (graph.getModel().isVertex(cell) && graph.getModel().getChildCount(cell) == 0)
                    {
                        var geo = graph.getCellGeometry(cell);

                        if (geo != null)
                        {
                            // Rotates the size and position in the geometry
                            geo = geo.clone();
                            geo.x += geo.width / 2 - geo.height / 2;
                            geo.y += geo.height / 2 - geo.width / 2;
                            var tmp = geo.width;
                            geo.width = geo.height;
                            geo.height = tmp;
                            graph.getModel().setGeometry(cell, geo);

                            // Reads the current direction and advances by 90 degrees
                            var state = graph.view.getState(cell);

                            if (state != null)
                            {
                                var dir = state.style[mxConstants.STYLE_DIRECTION] || 'east'/*default*/;

                                if (dir == 'east')
                                {
                                    dir = 'south';
                                }
                                else if (dir == 'south')
                                {
                                    dir = 'west';
                                }
                                else if (dir == 'west')
                                {
                                    dir = 'north';
                                }
                                else if (dir == 'north')
                                {
                                    dir = 'east';
                                }

                                graph.setCellStyles(mxConstants.STYLE_DIRECTION, dir, [cell]);
                            }
                        }
                    }
                }
            }
            finally
            {
                graph.getModel().endUpdate();
            }
        }
    }, null, null, 'Ctrl+R');

    // View actions
    this.addAction('actualSize', function()
    {
        graph.zoomTo(1);
    });
    this.addAction('zoomIn', function() {
        graph.zoomIn();
    }, null, null, 'Add');
    this.addAction('zoomOut', function() {
        graph.zoomOut();
    }, null, null, 'Subtract');
    this.addAction('fitWindow', function() {
        graph.fit();
    });

    this.addAction('fitPage', mxUtils.bind(this, function()
    {
        if (!graph.pageVisible)
        {
            this.get('pageView').funct();
        }

        var fmt = graph.pageFormat;
        var ps = graph.pageScale;
        var cw = graph.container.clientWidth - 20;
        var ch = graph.container.clientHeight - 20;

        var scale = Math.floor(100 * Math.min(cw / fmt.width / ps, ch / fmt.height / ps)) / 100;
        graph.zoomTo(scale);

        graph.container.scrollLeft = Math.round(graph.view.translate.x * scale - Math.max(10, (graph.container.clientWidth - fmt.width * ps * scale) / 2));
        graph.container.scrollTop = Math.round(graph.view.translate.y * scale - Math.max(10, (graph.container.clientHeight - fmt.height * ps * scale) / 2));
    }));
    this.addAction('fitPageWidth', mxUtils.bind(this, function()
    {
        if (!graph.pageVisible)
        {
            this.get('pageView').funct();
        }

        var fmt = graph.pageFormat;
        var ps = graph.pageScale;
        var cw = graph.container.clientWidth - 20;

        var scale = Math.floor(100 * cw / fmt.width / ps) / 100;
        graph.zoomTo(scale);

        graph.container.scrollLeft = Math.round(graph.view.translate.x * scale - Math.max(10, (graph.container.clientWidth - fmt.width * ps * scale) / 2));
        graph.container.scrollTop = Math.round(graph.view.translate.y * scale - Math.max(10, (graph.container.clientHeight - fmt.height * ps * scale) / 2));
    }));
    this.put('customZoom', new Action(mxResources.get('custom'), function()
    {
        var value = mxUtils.prompt(mxResources.get('enterValue') + ' (%)', parseInt(graph.getView().getScale() * 100));

        if (value != null && value.length > 0 && !isNaN(parseInt(value)))
        {
            graph.zoomTo(parseInt(value) / 100);
        }
    }));

    // Option actions
    var action = null;
    action = this.addAction('grid', function()
    {
        graph.setGridEnabled(!graph.isGridEnabled());
        editor.updateGraphComponents();
    }, null, null, 'Ctrl+Shift+G');
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.isGridEnabled();
    });
    action = this.addAction('guides', function() {
        graph.graphHandler.guidesEnabled = !graph.graphHandler.guidesEnabled;
    });
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.graphHandler.guidesEnabled;
    });
    action = this.addAction('tooltips', function()
    {
        graph.tooltipHandler.setEnabled(!graph.tooltipHandler.isEnabled());
    });
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.tooltipHandler.isEnabled();
    });
    action = this.addAction('navigation', function()
    {
        graph.foldingEnabled = !graph.foldingEnabled;
        graph.view.revalidate();
    });
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.foldingEnabled;
    });
    action = this.addAction('scrollbars', function()
    {
        graph.scrollbars = !graph.scrollbars;
        editor.updateGraphComponents();

        if (!graph.scrollbars)
        {
            var t = graph.view.translate;
            graph.view.setTranslate(t.x - graph.container.scrollLeft / graph.view.scale, t.y - graph.container.scrollTop / graph.view.scale);
            graph.container.scrollLeft = 0;
            graph.container.scrollTop = 0;
            graph.sizeDidChange();
        }
        else
        {
            var dx = graph.view.translate.x;
            var dy = graph.view.translate.y;

            graph.view.translate.x = 0;
            graph.view.translate.y = 0;
            graph.sizeDidChange();
            graph.container.scrollLeft -= Math.round(dx * graph.view.scale);
            graph.container.scrollTop -= Math.round(dy * graph.view.scale);
        }
    }, !mxClient.IS_TOUCH);
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.container.style.overflow == 'auto';
    });
    action = this.addAction('pageView', mxUtils.bind(this, function()
    {
        graph.pageVisible = !graph.pageVisible;
        graph.pageBreaksVisible = graph.pageVisible;
        graph.preferPageSize = graph.pageBreaksVisible;
        graph.view.validate();
        graph.sizeDidChange();

        editor.updateGraphComponents();
        editor.outline.update();

        if (mxUtils.hasScrollbars(graph.container))
        {
            if (graph.pageVisible)
            {
                graph.container.scrollLeft -= 20;
                graph.container.scrollTop -= 20;
            }
            else
            {
                graph.container.scrollLeft += 20;
                graph.container.scrollTop += 20;
            }
        }
    }));
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.pageVisible;
    });
    this.put('pageBackgroundColor', new Action(mxResources.get('backgroundColor'), function()
    {
        var apply = function(color)
        {
            graph.background = color;
            editor.updateGraphComponents();
        };

        var cd = new ColorDialog(ui, graph.background || 'none', apply);
        ui.showDialog(cd.container, 220, 400, true, false);

        if (!mxClient.IS_TOUCH)
        {
            cd.colorInput.focus();
        }
    }));
    action = this.addAction('connect', function()
    {
        graph.setConnectable(!graph.connectionHandler.isEnabled());
    }, null, null, 'Ctrl+Q');
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.connectionHandler.isEnabled();
    });
    action = this.addAction('copyConnect', function()
    {
        graph.connectionHandler.setCreateTarget(!graph.connectionHandler.isCreateTarget());
    });
    action.setToggleAction(true);
    action.setSelectedCallback(function() {
        return graph.connectionHandler.isCreateTarget();
    });

    // Help actions
    this.addAction('help', function()
    {
        var ext = '';

        if (mxResources.isLanguageSupported(mxClient.language))
        {
            ext = '_' + mxClient.language;
        }

        window.open(RESOURCES_PATH + '/help' + ext + '.html');
    });
    this.put('about', new Action(mxResources.get('about') + ' Graph Editor', function()
    {
        ui.showDialog(new AboutDialog(ui).container, 320, 280, true, true);
    }, null, null, 'F1'));

    // Font style actions
    var toggleFontStyle = mxUtils.bind(this, function(key, style)
    {
        this.addAction(key, function()
        {
            graph.toggleCellStyleFlags(mxConstants.STYLE_FONTSTYLE, style);
        });
    });

    toggleFontStyle('bold', mxConstants.FONT_BOLD);
    toggleFontStyle('italic', mxConstants.FONT_ITALIC);
    toggleFontStyle('underline', mxConstants.FONT_UNDERLINE);

    // Color actions
    this.addAction('fontColor', function() {
        ui.menus.pickColor(mxConstants.STYLE_FONTCOLOR);
    });
    this.addAction('strokeColor', function() {
        ui.menus.pickColor(mxConstants.STYLE_STROKECOLOR);
    });
    this.addAction('fillColor', function() {
        ui.menus.pickColor(mxConstants.STYLE_FILLCOLOR);
    });
    this.addAction('gradientColor', function() {
        ui.menus.pickColor(mxConstants.STYLE_GRADIENTCOLOR);
    });
    this.addAction('backgroundColor', function() {
        ui.menus.pickColor(mxConstants.STYLE_LABEL_BACKGROUNDCOLOR);
    });
    this.addAction('borderColor', function() {
        ui.menus.pickColor(mxConstants.STYLE_LABEL_BORDERCOLOR);
    });

    // Format actions
    this.addAction('shadow', function() {
        graph.toggleCellStyles(mxConstants.STYLE_SHADOW);
    });
    this.addAction('dashed', function() {
        graph.toggleCellStyles(mxConstants.STYLE_DASHED);
    });
    this.addAction('rounded', function() {
        graph.toggleCellStyles(mxConstants.STYLE_ROUNDED);
    });
    this.addAction('curved', function() {
        graph.toggleCellStyles(mxConstants.STYLE_CURVED);
    });
    this.addAction('style', function()
    {
        var cells = graph.getSelectionCells();

        if (cells != null && cells.length > 0)
        {
            var model = graph.getModel();
            var style = mxUtils.prompt(mxResources.get('enterValue') + ' (' + mxResources.get('style') + ')',
                    model.getStyle(cells[0]) || '');

            if (style != null)
            {
                graph.setCellStyle(style, cells);
            }
        }
    });
    this.addAction('setAsDefaultEdge', function()
    {
        graph.setDefaultEdge(graph.getSelectionCell());
    });
    this.addAction('addWaypoint', function()
    {
        var cell = graph.getSelectionCell();

        if (cell != null && graph.getModel().isEdge(cell))
        {
            var handler = editor.graph.selectionCellsHandler.getHandler(cell);

            if (handler instanceof mxEdgeHandler)
            {
                var t = graph.view.translate;
                var s = graph.view.scale;
                var dx = t.x;
                var dy = t.y;

                var parent = graph.getModel().getParent(cell);
                var pgeo = graph.getCellGeometry(parent);

                if (graph.getModel().isVertex(parent) && pgeo != null)
                {
                    dx += pgeo.x;
                    dy += pgeo.y;
                }

                handler.addPointAt(handler.state, graph.panningHandler.triggerX / s - dx, graph.panningHandler.triggerY / s - dy);
            }
        }
    });
    this.addAction('removeWaypoint', function()
    {
        // TODO: Action should run with "this" set to action
        var rmWaypointAction = ui.actions.get('removeWaypoint');

        if (rmWaypointAction.handler != null)
        {
            // NOTE: Popupevent handled and action updated in Menus.createPopupMenu
            rmWaypointAction.handler.removePoint(rmWaypointAction.handler.state, rmWaypointAction.index);
        }
    });
    this.addAction('image', function()
    {
        function updateImage(value, w, h)
        {
            var select = null;
            var cells = graph.getSelectionCells();

            graph.getModel().beginUpdate();
            try
            {
                // Inserts new cell if no cell is selected
                if (cells.length == 0)
                {
                    var gs = graph.getGridSize();
                    cells = [graph.insertVertex(graph.getDefaultParent(), null, '', gs, gs, w, h)];
                    select = cells;
                }

                graph.setCellStyles(mxConstants.STYLE_IMAGE, value, cells);
                graph.setCellStyles(mxConstants.STYLE_SHAPE, 'image', cells);

                if (graph.getSelectionCount() == 1)
                {
                    if (w != null && h != null)
                    {
                        var cell = cells[0];
                        var geo = graph.getModel().getGeometry(cell);

                        if (geo != null)
                        {
                            geo = geo.clone();
                            geo.width = w;
                            geo.height = h;
                            graph.getModel().setGeometry(cell, geo);
                        }
                    }
                }
            }
            finally
            {
                graph.getModel().endUpdate();
            }

            if (select != null)
            {
                graph.setSelectionCells(select);
                graph.scrollCellToVisible(select[0]);
            }
        }
        ;

        var value = '';
        var state = graph.getView().getState(graph.getSelectionCell());

        if (state != null)
        {
            value = state.style[mxConstants.STYLE_IMAGE] || value;
        }

        value = mxUtils.prompt(mxResources.get('enterValue') + ' (' + mxResources.get('url') + ')', value);

        if (value != null)
        {
            if (value.length > 0)
            {
                var img = new Image();

                img.onload = function()
                {
                    updateImage(value, img.width, img.height);
                };
                img.onerror = function()
                {
                    mxUtils.alert(mxResources.get('fileNotFound'));
                };

                img.src = value;
            }
        }
    });
};

/**
 * Registers the given action under the given name.
 */
Actions.prototype.addAction = function(key, funct, enabled, iconCls, shortcut)
{
    return this.put(key, new Action(mxResources.get(key), funct, enabled, iconCls, shortcut));
};

/**
 * Registers the given action under the given name.
 */
Actions.prototype.put = function(name, action)
{
    this.actions[name] = action;

    return action;
};

/**
 * Returns the action for the given name or null if no such action exists.
 */
Actions.prototype.get = function(name)
{
    return this.actions[name];
};

/**
 * Constructs a new action for the given parameters.
 */
function Action(label, funct, enabled, iconCls, shortcut)
{
    mxEventSource.call(this);
    this.label = label;
    this.funct = funct;
    this.enabled = (enabled != null) ? enabled : true;
    this.iconCls = iconCls;
    this.shortcut = shortcut;
}
;

// Action inherits from mxEventSource
mxUtils.extend(Action, mxEventSource);

/**
 * Sets the enabled state of the action and fires a stateChanged event.
 */
Action.prototype.setEnabled = function(value)
{
    if (this.enabled != value)
    {
        this.enabled = value;
        this.fireEvent(new mxEventObject('stateChanged'));
    }
};

/**
 * Sets the enabled state of the action and fires a stateChanged event.
 */
Action.prototype.setToggleAction = function(value)
{
    this.toggleAction = value;
};

/**
 * Sets the enabled state of the action and fires a stateChanged event.
 */
Action.prototype.setSelectedCallback = function(funct)
{
    this.selectedCallback = funct;
};

/**
 * Sets the enabled state of the action and fires a stateChanged event.
 */
Action.prototype.isSelected = function()
{
    return this.selectedCallback();
};
